package site.kitcheng.springboottest.infra.config.security;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import site.kitcheng.springboottest.infra.utils.KeyConverter;
import site.kitcheng.springboottest.infra.utils.RSAEncryptWithSalt;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;

/**
 * ClassName: RsaPasswordEncoder
 * Package: site.kitcheng.springboottest.infra.config.security
 * Description:
 *
 * @Author jiangCheng
 * @Create 2025/2/25 9:35
 * @Version 1.0
 */
//@Component
public class RsaPasswordEncoder implements PasswordEncoder {

    @Autowired
    private MySecurityPropertiesConfig mySecurityPropertiesConfig;
    @Override
    public String encode(CharSequence rawPassword) {
        if (rawPassword == null) {
            throw new IllegalArgumentException("Raw password must not be null");
        }
        try {
            String rawPasswordStr = (String) rawPassword;
            return encrypt(rawPasswordStr);

        } catch (Exception e) { // 处理I/O相关的问题，比如读取公钥文件时出错
            throw new RuntimeException("IO exception during encryption setup", e);
        }
    }


    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        if (StringUtils.isEmpty(encodedPassword)){
         return false;
        }
        String rawPasswordStr = (String) rawPassword;
        try {
            String encrypt = encrypt(rawPasswordStr);
            return encrypt.equals(encodedPassword);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }


    public  String encrypt(String password) throws Exception {
            PublicKey publicKey = KeyConverter.getPublicKeyFromBase64(mySecurityPropertiesConfig.getPublicKey());
            String encryptedPassword = RSAEncryptWithSalt.encryptWithSalt(password, publicKey);
            return encryptedPassword;
    }
}
